﻿using Transformable_Engine_v2.Engine.Animation.ColorAnimation;
using Transformable_Engine_v2.Engine.Animation.PositionAnimation;
using Transformable_Engine_v2.Engine.Animation.Trajectory;
using Transformable_Engine_v2.Engine.GameObjects.Containers;
using Transformable_Engine_v2.Engine.Graphics;
using Transformable_Engine_v2.Engine.Helper;
using Transformable_Engine_v2.Engine.Time;
using Transformable_Engine_v2.Engine.Transformable_Math.Geometry;

namespace Super_Management_Mayhem.Screens.Menu
{
    public class ItemWheel : Container
    {
        public int SelectedItemIndex { get; private set; }

        private int _visibleLevels;

        private float _radius;

        private Timer _cycleTimer;

        private int _selectionTime;

        private Container _itemContainer;
        private Container _selectedCursor;

        public ItemWheel(int selectedIndex, int selectionTime, int visibleLevels, float radius, Container selectedCursor, params ImageContainer[] children)
        {
            _selectedCursor = selectedCursor;

            _itemContainer = new Container();

            _itemContainer.AddChildren(children);
            AddChildren(_itemContainer, _selectedCursor);

            SelectedItemIndex = selectedIndex;
            _visibleLevels = visibleLevels;
            _radius = radius;
            _selectionTime = selectionTime;

            PositionItems(true);

            _cycleTimer = new Timer(_selectionTime, false, null);
            AddTimers(_cycleTimer);
        }

        public void CycleLeft()
        {
            if(_cycleTimer.IsStarted)
                return;

            SelectedItemIndex--;

            if(SelectedItemIndex < 0)
                SelectedItemIndex = _itemContainer.Children.Count - 1;

            PositionItems(false);
        }

        public void CycleRight()
        {
            if(_cycleTimer.IsStarted)
                return; 

            SelectedItemIndex++;

            if(SelectedItemIndex >= _itemContainer.Children.Count)
                SelectedItemIndex = 0;

            PositionItems(false);
        }

        float GetAlphaFromIndex(int index)
        {
            int offsetIndex = index - SelectedItemIndex;

            if(offsetIndex < 0)
                offsetIndex += _itemContainer.Children.Count;

            for(int i = 0; i < _visibleLevels; i++)
            {
                if(offsetIndex == i || offsetIndex == _itemContainer.Children.Count - i)
                    return 255 - ((float)i / _visibleLevels) * 255;
            }

            return 0;
        }

        void PositionItems(bool immediate)
        {
            for (int i = 0; i < _itemContainer.Children.Count; i++)
            {
                ImageContainer item = (ImageContainer) _itemContainer.Children[i];

                TE_Vector2 calculatedPosition = new TE_Vector2(((float) (i - SelectedItemIndex) / _itemContainer.Children.Count - 0.25).TimesTwoPi(), _radius);
                if(immediate)
                {
                    item.PositionGridBound = calculatedPosition;
                    item.Color = new Color(item.Color, GetAlphaFromIndex(i));

                    if(i == SelectedItemIndex)
                    {
                        _selectedCursor.Position = item.Position;
                    }
                }
                else
                {
                    item.ClearAnimation();
                    item.AddAnimations(new PositionAnimation(new QuadraticEasing(BaseTrajectory.Easing.EaseInAndOut), calculatedPosition, _selectionTime, false, 0));
                    item.AddAnimations(new ColorAnimation(new LinearEasing(), new Color(item.Color, GetAlphaFromIndex(i)), _selectionTime, false, 0));

                    if(i == SelectedItemIndex)
                    {
                        _selectedCursor.Position = item.Position;
                        _selectedCursor.ClearAnimation<PositionAnimation>();
                        _selectedCursor.AddAnimations(new PositionAnimation(new QuadraticEasing(BaseTrajectory.Easing.EaseInAndOut), calculatedPosition, _selectionTime, false, 0));
                    }
                }
            }

            if(!immediate)
                _cycleTimer.Reset();
        }
    }
}